package com.ykzhujiang.lovespirit;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import javax.cache.Cache;
import javax.cache.CacheException;
import javax.cache.CacheFactory;
import javax.cache.CacheManager;
import javax.jdo.PersistenceManager;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.memcache.stdimpl.GCacheFactory;
import com.ykzhujiang.lovespirit.entity.LSUser;
import com.ykzhujiang.lovespirit.entity.Notice;
import com.ykzhujiang.lovespirit.util.DataManager;
import com.ykzhujiang.lovespirit.util.PMF;

public class EmailServlet extends HttpServlet {
	private static final Logger logger = Logger.getLogger(EmailServlet.class
			.getName());

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		logger.info("try to send emails");
		StringBuffer msgBody = new StringBuffer();
		String query;
		Calendar date = Calendar.getInstance();
		date.set(Calendar.HOUR_OF_DAY, 0);
		date.set(Calendar.MINUTE, 0);
		date.set(Calendar.SECOND, 0);
		long INTERVAL = 24 * 3600000L;
		Cache cache = null;
		HashMap<Integer, Date> cprops = new HashMap<Integer, Date>();
		logger.info("cache expiration:"
				+ new Date(date.getTimeInMillis() + INTERVAL));
		cprops.put(GCacheFactory.EXPIRATION, new Date(date.getTimeInMillis()
				+ INTERVAL));

		try {
			CacheFactory cacheFactory = CacheManager.getInstance()
					.getCacheFactory();
			cache = cacheFactory.createCache(cprops);

		} catch (CacheException e) {
			logger.warning(e.getMessage());
		}
		if (cache == null || !cache.containsKey(EmailServlet.MEMKEY_EMAIL)) {
			long begin = (date.getTimeInMillis() - INTERVAL) * 1000;

			query = "select from " + Notice.class.getName() + " where date > "
					+ begin + " && date < " + date.getTimeInMillis() * 1000
					+ " order by date desc, hot desc range 0, 20";
			List<Notice> results = (List<Notice>) DataManager.getData(query,
					false, null);
			for (int i = 0; i < results.size(); i++) {
				Notice notice = results.get(i);
				if (notice.getHot() >= MIN_HOT)
					msgBody.append(notice.getTitle()
							+ "\n"
							+ notice.getWriter()
							+ "\n"
							+ notice.getSourceUrl()
							+ "\n"
							+ notice.getContent().substring(
									0,
									Math.min(notice.getContent().length(),
											MAX_CONTENT_LENGTH)).trim()
							+ " ..." + "\n\n\n");
			}
			if (cache != null) {
				logger.info("try to cache email message");
				cache.put(EmailServlet.MEMKEY_EMAIL, msgBody.toString());
			}
		} else {
			logger.info("cache hit");
			msgBody.append((String) cache.get(EmailServlet.MEMKEY_EMAIL));
		}
		if (msgBody.length() == 0)
			return;
		Properties props = new Properties();
		Session session = Session.getDefaultInstance(props, null);

		query = "select from " + LSUser.class.getName() + " where sendDate < "
				+ (date.getTimeInMillis() * 1000)
				+ " order by sendDate asc range 0, 5";

		List<LSUser> users = (List<LSUser>) DataManager.getData(query, false,
				null);
		Date cur = new Date();
		logger.info("current date:" + cur);
		logger.info("sending emails");
		for (int i = 0; users != null && i < users.size(); i++) {

			try {
				LSUser user = users.get(i);
				logger.info("sending to :" + user.getEmail());
				Message msg = new MimeMessage(session);
				msg.setFrom(new InternetAddress(HOST_EMAIL));
				msg.addRecipient(Message.RecipientType.TO, new InternetAddress(
						user.getEmail(), user.getUser().getNickname()));
				msg.setSubject("Love Spirit Digest " + cur);
				msg.setText(msgBody.toString());
				Transport.send(msg);
				user.setSendDate(cur);
				DataManager.addData(user);

			} catch (AddressException e) {
				logger.warning(e.getMessage());
			} catch (MessagingException e) {
				logger.warning(e.getMessage());
			}
		}

		resp.getWriter().println("done");
	}

	public static final String HOST_EMAIL = "ch1namc3r@gmail.com";

	private static final int MAX_CONTENT_LENGTH = 100;

	private static final int MIN_HOT = 3;

	private static final String MEMKEY_EMAIL = "MEM_KEY_EMAIL";
}